package com.linden.std.service.session.impl;

import com.alibaba.fastjson.JSON;
import com.linden.std.constant.CommonConstant;
import com.linden.std.domain.vo.UserVO;
import com.linden.std.service.ISysUserService;
import com.linden.std.service.session.SessionService;
import com.linden.std.util.RedisTemplateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.util.Collections;
import java.util.List;

/**
 * Session管理服务实现类
 * 负责用户信息和权限信息的分离存储与同步更新
 */
@Slf4j
@Service
public class SessionServiceImpl implements SessionService {

    @Autowired
    private RedisTemplateUtil redisTemplateUtil;

    @Autowired
    private ISysUserService userService;

    @Value("${std.security.token.access-timeout:7200}")
    private Integer cacheTimeout;

    @Override
    public void refreshUserInfoToSession(Long userId, HttpSession session) {
        if (userId == null || session == null) {
            return;
        }

        try {
            // 从Redis获取最新的用户信息
            UserVO userVO = getUserInfoFromCache(userId);
            if (userVO != null) {
                // 同步到Session
                session.setAttribute(CommonConstant.SESSION_USER_KEY, userVO);
                log.debug("刷新用户{}基本信息到Session成功", userId);
            } else {
                log.warn("从Redis获取用户{}信息失败", userId);
            }
        } catch (Exception e) {
            log.error("刷新用户{}信息到Session失败: {}", userId, e.getMessage());
        }
    }

    @Override
    public void refreshPermissionToSession(Long userId, HttpSession session) {
        if (userId == null || session == null) {
            return;
        }

        try {
            // 从Redis获取最新的权限信息
            List<String> permissions = getUserPermissionsFromCache(userId);
            // 同步到Session
            session.setAttribute(CommonConstant.SESSION_PERMISSION_KEY, permissions);
            log.debug("刷新用户{}权限信息到Session成功，权限数量: {}", userId, permissions.size());
        } catch (Exception e) {
            log.error("刷新用户{}权限信息到Session失败: {}", userId, e.getMessage());
        }
    }

    @Override
    public void refreshUserAndPermissionToSession(Long userId, HttpSession session) {
        if (userId == null || session == null) {
            return;
        }

        // 同时刷新用户信息和权限信息
        refreshUserInfoToSession(userId, session);
        refreshPermissionToSession(userId, session);
        log.debug("同时刷新用户{}的基本信息和权限信息到Session完成", userId);
    }

    @Override
    public void cacheUserInfo(Long userId, UserVO userVO) {
        if (userId == null || userVO == null) {
            return;
        }

        try {
            String cacheKey = CommonConstant.REDIS_LOGIN_USER_KEY_PREFIX + userId;
            redisTemplateUtil.set(cacheKey, JSON.toJSONString(userVO), cacheTimeout);
            log.debug("缓存用户{}基本信息到Redis成功", userId);
        } catch (Exception e) {
            log.error("缓存用户{}基本信息失败: {}", userId, e.getMessage());
        }
    }

    @Override
    public void cacheUserPermissions(Long userId, List<String> permissions) {
        if (userId == null) {
            return;
        }

        try {
            String cacheKey = CommonConstant.REDIS_USER_PERMISSION_KEY_PREFIX + userId;
            List<String> safePermissions = permissions != null ? permissions : Collections.emptyList();
            redisTemplateUtil.set(cacheKey, JSON.toJSONString(safePermissions), cacheTimeout);
            log.debug("缓存用户{}权限信息到Redis成功，权限数量: {}", userId, safePermissions.size());
        } catch (Exception e) {
            log.error("缓存用户{}权限信息失败: {}", userId, e.getMessage());
        }
    }

    @Override
    public UserVO getUserInfoFromCache(Long userId) {
        if (userId == null) {
            return null;
        }

        try {
            String cacheKey = CommonConstant.REDIS_LOGIN_USER_KEY_PREFIX + userId;
            String userInfoJson = redisTemplateUtil.get(cacheKey);

            if (StringUtils.isNotBlank(userInfoJson)) {
                return JSON.parseObject(userInfoJson, UserVO.class);
            }
        } catch (Exception e) {
            log.error("从Redis获取用户{}信息失败: {}", userId, e.getMessage());
        }

        return null;
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<String> getUserPermissionsFromCache(Long userId) {
        if (userId == null) {
            return Collections.emptyList();
        }

        try {
            String cacheKey = CommonConstant.REDIS_USER_PERMISSION_KEY_PREFIX + userId;
            String permissionsJson = redisTemplateUtil.get(cacheKey);

            if (StringUtils.isNotBlank(permissionsJson)) {
                return JSON.parseArray(permissionsJson, String.class);
            }
        } catch (Exception e) {
            log.error("从Redis获取用户{}权限信息失败: {}", userId, e.getMessage());
        }

        return Collections.emptyList();
    }

    @Override
    public UserVO getUserInfoFromSession(HttpSession session) {
        if (session == null) {
            return null;
        }

        try {
            return (UserVO) session.getAttribute(CommonConstant.SESSION_USER_KEY);
        } catch (Exception e) {
            log.error("从Session获取用户信息失败: {}", e.getMessage());
            return null;
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<String> getUserPermissionsFromSession(HttpSession session) {
        if (session == null) {
            return Collections.emptyList();
        }

        try {
            List<String> permissions = (List<String>) session.getAttribute(CommonConstant.SESSION_PERMISSION_KEY);
            return permissions != null ? permissions : Collections.emptyList();
        } catch (Exception e) {
            log.error("从Session获取用户权限信息失败: {}", e.getMessage());
            return Collections.emptyList();
        }
    }

    @Override
    public void clearUserCache(Long userId) {
        if (userId == null) {
            return;
        }

        try {
            String userCacheKey = CommonConstant.REDIS_LOGIN_USER_KEY_PREFIX + userId;
            String permissionCacheKey = CommonConstant.REDIS_USER_PERMISSION_KEY_PREFIX + userId;

            redisTemplateUtil.delete(userCacheKey);
            redisTemplateUtil.delete(permissionCacheKey);

            log.debug("清理用户{}缓存信息成功", userId);
        } catch (Exception e) {
            log.error("清理用户{}缓存信息失败: {}", userId, e.getMessage());
        }
    }

    @Override
    public void clearSessionUserInfo(HttpSession session) {
        if (session == null) {
            return;
        }

        try {
            session.removeAttribute(CommonConstant.SESSION_USER_KEY);
            session.removeAttribute(CommonConstant.SESSION_PERMISSION_KEY);
            log.debug("清理Session用户信息成功");
        } catch (Exception e) {
            log.error("清理Session用户信息失败: {}", e.getMessage());
        }
    }
}